<?php

namespace api\controller;

// +----------------------------------------------------------------------
// | 计划控制层
// +----------------------------------------------------------------------

use common\controller\VerifyController;
use common\exception\LogicException;
use common\model\PlanModel;
use common\service\PlanService;
use common\validate\Plan;
use support\ErrorCode;
use think\Exception;
use think\Request;

class PlanController extends VerifyController
{
    /**
     * @var PlanService
     */
    protected $planService;

    public function __construct()
    {
        parent::__construct();
        $this->planService = PlanService::getInstance();
    }

    /**
     * 保存计划接口
     * @param Request $request
     * @return \think\Response
     * @throws \think\Exception
     */
    public function save(Request $request)
    {
        $param = $request->param();
        try {
            $resData = $this->planService->save($param['data']);
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 批量保存计划接口
     * @param Request $request
     * @return \think\Response
     * @throws \Throwable
     * @throws \think\Exception
     */
    public function saveBatch(Request $request)
    {
        $param = $request->param();
        $data = $param['data']['tasks'];
        $validator = new Plan();
        $validator->scene("SaveBatch");

        foreach ($data as $item) {
            $flag = $validator->check($item);
            if ($flag === false) {
                throw_strack_exception($validator->getError(), ErrorCode::PLAN_BATCH_SAVE_PARAM);
            }
        }

        $resData = $this->planService->saveBatch($param['data']);
        return json(success_response('', $resData));
    }

    /**
     * 查询集分类tree
     * @param Request $request
     * @return \think\Response
     */
    public function getEpisodesStepCategoryTree(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->getEpisodesStepCategoryTree($param['param']);
        return json(success_response("OK", $resData));
    }

    /**
     * 查询分类集tree
     * @param Request $request
     * @return \think\Response
     */
    public function getStepCategoryEpisodesTree(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->getStepCategoryEpisodesTree($param['param']);
        return json(success_response("OK", $resData));
    }

    /**
     * 项目集计划查询
     * @param Request $request
     * @return \think\Response
     */
    public function getEpisodePlan(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->getEpisodePlan($param['param']);
        return json($resData);
    }

    /**
     * 项目分类计划查询
     * @param Request $request
     * @return \think\Response
     * @throws \think\Exception
     */
    public function getStepCategoryPlan(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->getStepCategoryPlan($param['param']);
        return json($resData);
    }

    /**
     * 获得集工序分类排期
     * @param Request $request
     * @return \think\Response
     * @throws \think\Exception
     */
    public function getEpisodeStepCategoryPlan(Request $request)
    {
        $param = $request->param();
        try {
            $resData = $this->planService->getEpisodeStepCategoryPlan($param['param']);
            return json($resData);
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 获取实体的计划
     * @param Request $request
     * @return \think\Response
     * @throws \think\Exception
     */
    public function getEntityPlan(Request $request)
    {
        $param = $request->param();
        $code = $param['param']['filter']['code'];
        $projectId = $param['param']['filter']['project_id'];
        $episodeId = $param['param']['filter']['episode_id'];

        try {
            $resData = [];
            if ($code === 'asset') {
                $resData = $this->planService->getAssetEntityPlan($code, $projectId, $episodeId, $param['param']);
            } elseif ($code === 'shot') {
                $resData = $this->planService->getShotEntityStepPlan($code, $projectId, $episodeId, $request->getTenantId(), $param['param']);
            }
            return json($resData);
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    public function findPlan(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->findPlan($param['param']);
        return json(success_response("OK", $resData));
    }

    /**
     * 给实体打组
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function createGroup(Request $request)
    {
        $param = $request->param();
        try {
            $resData = $this->planService->createGroup($param);
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }

        return json(success_response("OK", $resData));
    }

    /**
     * 解除组
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function deleteGroup(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->deleteGroup($param['param']['filter']);
        return json(success_response("OK", $resData));
    }

    /**
     * 设置组时间
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function updateGroup(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->updateGroup($param['param']['filter'], $param['data']);
        return json(success_response("OK", $resData));
    }


    /**
     * 获得工序分类集排期
     * @param Request $request
     * @return \think\Response
     */
    public function getStepCategoryEpisodePlan(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->getStepCategoryEpisodePlan($param['param']);
        return json($resData);
    }

    /**
     * 产能计算
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function calculateCapacity(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->calculateCapacity($param['param'], $request->getTenantId());
        return json(success_response("OK", $resData));
    }

    /**
     * 计划面板数据
     * @param Request $request
     * @return \think\Response
     */
    public function planPanel(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->planPanel($param['param'], $request->getTenantId());
        return json($resData);
    }

    /**
     * 未排期数据
     * @param Request $request
     * @return \think\Response
     */
    public function unPlannedData(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->unPlannedData($param['param'], $request->getTenantId());
        return json(success_response("OK", $resData));
    }

    /**
     * 查询集分类计划列表 (如果集分类计划为空 那么使用集计划补充)
     * @param Request $request
     * @return \think\Response
     */
    public function getFixedEpisodeStepCategoryPlan(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->planService->getFixedEpisodeStepCategoryPlan($param['filter']['project_id'], $param['filter']['step_category_id']);
        return json(success_response("OK", $resData));
    }

    /**
     * 获取项目计划列表
     * @param Request $request
     * @return \think\Response
     */
    public function getProjectPlanList(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->planService->getProjectPlanList($param);
        return json(success_response("OK", $resData));
    }

    /**
     * 获取计划项目集下的统计
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     */
    public function getPlanProjectEpisodeCount(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->planService->getPlanProjectEpisodeCount($param);
        return json(success_response("OK", $resData));
    }

    /**
     * 获取计划项目列表
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function getStepCategoryPlanProjectList(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->planService->getStepCategoryPlanProjectList($param, $request->getUserId());
        return json(success_response("OK", $resData));
    }

    /**
     * 多项目计划列表
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function getMultiProjectPlanList(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->planService->getMultiProjectPlanList($param, $request->getUserId());
        return json(success_response("OK", $resData));
    }

    /**
     * 保存工序分类计划
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     * @throws \Throwable
     */
    public function saveStepCategoryPlan(Request $request)
    {
        $param = $request->param()['data'];
        $validate = new Plan();
        if (empty($param["plan"]["id"])) {
            $validate->scene('AddStepCategoryPlan');
        } else {
            $validate->scene('UpdateStepCategoryPlan');
        }
        if (!$validate->check($param)) {
            throw_strack_exception($validate->getError(), ErrorCode::REQUEST_PARAM_ERROR);
        }

        try {
            $resData = $this->planService->saveStepCategoryPlan($param, $request->getUserId(), $request->getTenantId());
            return json(success_response("OK", $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 获取工序分类计划详情
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     * @throws \Throwable
     */
    public function getStepCategoryPlanDetail(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->planService->getStepCategoryPlanDetail($param, $request->getUserId());
        return json(success_response("OK", $resData));
    }

    /**
     * 获取排期-单项目
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     */
    public function getPlanOneProject(Request $request)
    {
        $param = $request->param();
        $StepCategoryIds = $param['param']['step_category_ids'] ?? '';
        $startTime = $param['param']['start_time'] ?? '';
        $endTime = $param['param']['end_time'] ?? '';
        $planType = $param['param']['plan_type'] ?? null;
        $showGlobal = $param['param']['show_global'] ?? 'yes';
        $taskName = $param['param']['task_name'] ?? null;
        $resData = $this->planService->getPlanOneProject($param['param'], $StepCategoryIds, $startTime, $endTime, $planType, $taskName, $showGlobal === 'yes');
        return json(success_response("OK", $resData));
    }

    /**
     * 获取排期-单项目
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     */
    public function getPlanOneProjectFind(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->getPlanOneProjectFind($param['param']);
        return json(success_response("OK", $resData));
    }

    /**
     * 移除代办计划
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     * @throws \Throwable
     */
    public function removeToDoPlan(Request $request)
    {
        $param = $request->param()['param']['filter'];
        $resData = $this->planService->removeToDoPlan($param);
        return json(success_response("OK", $resData));
    }

    /**
     * 批量修改工序分类计划
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     * @throws \Throwable
     */
    public function batchUpdateStepCategoryPlan(Request $request)
    {
        $data = $request->param()['data'];

        $validate = new Plan();
        $validate->scene('BatchUpdateStepCategoryPlanItem');
        foreach ($data as $item) {
            if (!empty($item["plan"]["id"])) {
                if (!$validate->check($item)) {
                    throw_strack_exception($validate->getError(), ErrorCode::REQUEST_PARAM_ERROR);
                }
            }
        }

        $validate->scene('BatchAddStepCategoryPlanItem');
        foreach ($data as $item) {
            if (empty($item["plan"]["id"])) {
                if (!$validate->check($item)) {
                    throw_strack_exception($validate->getError(), ErrorCode::REQUEST_PARAM_ERROR);
                }
            }
        }

        try {
            $resData = $this->planService->batchUpdateStepCategoryPlan($data, $request->getUserId(), $request->getTenantId());
            return json(success_response("OK", $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }

    }

    /**
     * 获取计划多项目
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     */
    public function getPlanMultiProject(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->planService->getPlanMultiProject($param, $request->getUserId());
        return json(success_response("OK", $resData));
    }

    /**
     * 获取排期详情实体列表
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     */
    public function getScheduleInfoEntityList(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->planService->getScheduleInfoEntityList($param, $request->getTenantId());
        return json(success_response("OK", $resData));
    }

    /**
     * 获取排期任务列表
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     */
    public function getScheduleInfoTaskList(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->planService->getScheduleInfoTaskList($param, $request->getTenantId());
        return json(success_response("OK", $resData));
    }

    /**
     * 获取验证结果
     * @param \think\Request $request
     * @return \think\Response
     * @throws \think\Exception
     */
    public function getValidatePlanResult(Request $request)
    {
        $param = $request->param()['param'];

        $planIds = $param['filter']['plan_ids'];
        $episodeId = $param['filter']['episode_id'];
        $resData = $this->planService->getValidatePlanResult($planIds, $episodeId);
        return json(success_response("OK", $resData));
    }

    /**
     * 计划指定集复制
     * @param \think\Request $request
     * @return \think\Response
     * @throws \think\Exception|\Throwable
     */
    public function planSpecifyEpisodeCopy(Request $request)
    {
        $param = $request->param()['param'];
        $planIds = $param['filter']['plan_ids'];
        $episodeId = $param['filter']['episode_id'];
        $userId = $param['filter']['user_id'] ?? $request->getUserId();
        $tenantId = $param['filter']['user_id'] ?? $request->getTenantId();
        try {
            $resData = $this->planService->planSpecifyEpisodeCopy($planIds, $episodeId, $userId, $tenantId);
            return json(success_response("OK", $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 获取单项目列表
     * @param \think\Request $request
     * @return \think\Response
     * @throws \think\Exception
     */
    public function getPlanOneProjectSelect(Request $request)
    {
        $param = $request->param();
        $resData = $this->planService->getPlanOneProjectSelect($param['param']);
        return json(success_response("OK", $resData));
    }

    /**
     * 创建排期确认
     * @param \think\Request $request
     * @return \think\Response
     * @throws \Throwable
     * @throws \think\Exception
     */
    public function createPlanConfirmation(Request $request)
    {
        $data = $request->param()['data'];
        try {
            $resData = $this->planService->createPlanConfirmation($data);
            return json(success_response("OK", $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 获取排期确认列表
     * @param \think\Request $request
     * @return \think\Response
     */
    public function getPlanConfirmList(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->planService->getPlanConfirmList($param);
        return json(success_response("OK", $resData));
    }

    /**
     * 批量更新排期确认
     * @param \think\Request $request
     * @return \think\Response
     * @throws \think\Exception
     */
    public function batchUpdatePlanConfirm(Request $request)
    {
        $data = $request->param()['data'];
        $resData = $this->planService->batchUpdatePlanConfirm($data);
        return json(success_response("OK", $resData));

    }

    /**
     *
     * 批量更新排期到任务
     * @param Request $request
     * @return \think\Response
     */
    public function batchUpdatePlanTimeTask(Request $request)
    {
        $data = $request->param()['data'];
        $resData = $this->planService->batchUpdatePlanTimeTask($data);
        return json(success_response("OK", $resData));
    }

    /**
     * 原计划排期节点
     */
    public function originalPlanNodeList(Request $request)
    {
        $param = $request->param()['param'];

        $resData = $this->planService->getOriginalPlanNode($param);

        return json(success_response("OK", $resData));
    }

    /**
     * 排期锁定
     */
    public function addPlanLock(Request $request)
    {
        $param = $request->param()['param'];
        try {
            $resData = $this->planService->addPlanLock($param);
            return json(success_response("OK", $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

}
